#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include "string.h"
#include "ArduinoJson.h"
#include "config.h"

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

StaticJsonDocument<600> bleRxjson;
BLEServer *pServer = NULL;
BLECharacteristic * pRxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
    deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
    }
};


class CharacteristicRxCallback: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
    std::string rxValue = pCharacteristic->getValue();

    if (rxValue.length() > 0) {
        Serial.print("Received Value: ");
        String rxdata=rxValue.c_str();
        Serial.println(rxdata);

        bleRxjson.clear();
        DeserializationError error = deserializeJson(bleRxjson,rxdata); 
        if((!error)){//在停止运行后，并且复位后才能进行重新运行
        const char *recssid,*recpasswd;
        pref.begin("config");
        if(bleRxjson.containsKey("SSID")){
        recssid=bleRxjson["SSID"];
        SSID=recssid;
        pref.putString("SSID",SSID);
        }
        if(bleRxjson.containsKey("PASSWD")){
        recpasswd=bleRxjson["PASSWD"];
        PASSWD=recpasswd;
        pref.putString("PASSWD",PASSWD);
        }
        pref.end();
        bleRxjson.clear();
        bleRxjson["SSID"]=SSID;
        bleRxjson["PASSWD"]=PASSWD;
        char state_doc[measureJson(bleRxjson) + 1];
        serializeJson(bleRxjson, state_doc, measureJson(bleRxjson) + 1);
        pRxCharacteristic->setValue(state_doc);
        xSemaphoreGiveFromISR(bleconfigSemaphore, NULL);//wifi连接成功，释放信号量
    }
    else{
        Serial.printf("Deserialization error:%d\n",error);
    }
    }
    }
};

void bleconfig(void *pvParameters)
{
    char devicename[40]="";
    sprintf(devicename,"controlbox%s",mac);
    BLEDevice::init(devicename);
    // Create the BLE Server
    pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    // Create the BLE Service
    BLEService *pService = pServer->createService(SERVICE_UUID);
    pRxCharacteristic = pService->createCharacteristic(
                        CHARACTERISTIC_UUID_RX,
                        BLECharacteristic::PROPERTY_WRITE|BLECharacteristic::PROPERTY_READ
                    );
    pRxCharacteristic->setCallbacks(new CharacteristicRxCallback());
    bleRxjson.clear();
    bleRxjson["SSID"]=SSID;
    bleRxjson["PASSWD"]=PASSWD;
    char state_doc[measureJson(bleRxjson) + 1];
    serializeJson(bleRxjson, state_doc, measureJson(bleRxjson) + 1);
    pRxCharacteristic->setValue(state_doc);
    // Start the service
    pService->start();
    // Start advertising
    pServer->getAdvertising()->start();
    uint32_t starttimes,nowtimes;
    starttimes=millis();
    for(;;){
        
        if (deviceConnected) {
        starttimes=millis();//当设备处于接入状态，刷新开始时间
        delay(10); // bluetooth stack will go into congestion, if too many packets are sent
        }
        nowtimes=millis();
        // disconnecting
        if (!deviceConnected && oldDeviceConnected) {
            delay(500); // give the bluetooth stack the chance to get things ready
            pServer->startAdvertising(); // restart advertising
            Serial.println("start advertising");
            oldDeviceConnected = deviceConnected;
        }
        // connecting
        if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
            oldDeviceConnected = deviceConnected;
        }
        delay(10);
        if (xSemaphoreTake(bleconfigSemaphore, 0) == pdTRUE){
            Serial.printf("ble config task delete\n");
            pService->stop();
            pServer->removeService(pService);
            delay(1000);
            esp_restart();
            // vTaskDelete(NULL);//任务自删除
        }
        if(nowtimes-starttimes>=300000){//开启蓝牙后若5min没有设备连接则重启
            esp_restart();
        }
    }
}